<template>
  <basic-drawer
    class="basic-drawer edit-cascade-node-drawer"
    title="节点编辑"
    :visible="visible"
    width="448px"
    :close-on-click-modal="false"
    ok-text="保存"
    :loading="loading || saveLoading"
    @close="handleClose"
    @cancel="emit('update:visible', false)"
    @ok="handleSave">
    <a-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      class="drawer-form"
      layout="vertical">
      <a-form-item
        label="节点名称"
        field="name"
        required
        hide-asterisk
        asterisk-position="end">
        <a-input
          v-model="formData.name"
          placeholder="请输入节点名称"
          :max-length="32"
          show-word-limit></a-input>
      </a-form-item>
      <a-form-item
        label="区域"
        field="region_id"
        required
        hide-asterisk
        asterisk-position="end">
        <a-select
          v-model="formData.region_id"
          placeholder="请选择区域"
          class="w-full">
          <a-option
            v-for="region in regionList"
            :key="region.id"
            :label="region.name"
            :value="region.id!"></a-option>
        </a-select>
      </a-form-item>
      <a-form-item
        class="reduce-gap"
        field="cascade_level"
        hide-asterisk
        asterisk-position="end">
        <template #label>
          <a-tooltip position="top">
            节点层级
            <template #content>
              <div>1. L2 节点负责回源，L1 节点自动从 L2 节点获取源站数据。</div>
              <div>2. 如果没有 L2 节点，L1 节点直接向源站请求回源。</div>
            </template>
            <i-icons-question
              class="cursor-pointer translate-y-2px question-icon" />
          </a-tooltip>
        </template>
        <a-radio-group v-model="formData.cascade_level">
          <a-radio :value="1">L1</a-radio>
          <a-radio :value="2">L2</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item
        class="reduce-gap"
        v-if="formData.cascade_level === 1"
        field="enable_resolve"
        required
        label="解析链路"
        hide-asterisk
        asterisk-position="end">
        <a-radio-group v-model="formData.enable_resolve">
          <a-radio :value="true">加入</a-radio>
          <a-radio :value="false">移除</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item
        v-else
        label="级联 IP"
        field="cascade_ip"
        hide-asterisk
        asterisk-position="end">
        <template #label>
          级联 IP
          <a-tooltip
            content="L1 节点回源当前 L2 节点时将会使用该 IP 地址。"
            position="top">
            <i-icons-question
              class="cursor-pointer translate-y-2px question-icon" />
          </a-tooltip>
        </template>
        <a-select
          v-model="formData.cascade_ip"
          placeholder="请选择级联 IP"
          class="w-full">
          <a-option label="使用主 IP" value=""></a-option>
          <a-option
            v-for="(ip, i) in formData.ips"
            :key="i"
            :label="ip"
            :value="ip"></a-option>
        </a-select>
      </a-form-item>
      <a-form-item
        v-if="formData.cascade_level === 2"
        label="级联端口"
        field="cascade_port"
        hide-asterisk
        asterisk-position="end"
        class="!mb-6"
        required>
        <template #label>
          级联端口
          <a-tooltip position="top" :content-style="{ 'max-width': '380px' }">
            <template #content>
              <div>L1 节点回源当前 L2 节点时将会使用该端口,不能为8888</div>
            </template>
            <i-icons-question
              class="cursor-pointer translate-y-2px question-icon" />
          </a-tooltip>
        </template>
        <a-input-number
          v-model="formData.cascade_port"
          hide-button
          :max="65535"
          :precision="0"
          placeholder="请输入级联端口"></a-input-number>
      </a-form-item>
      <a-form-item
        label="文件缓存路径"
        field="cache_path"
        hide-asterisk
        required>
        <template #label>
          <div class="flex gap-x-1 items-center">
            <span>文件缓存路径</span>
            <a-tooltip :content-style="{ 'max-width': '509px' }">
              <template #content>
                <span>
                  缓存路径请勿设置在 /opt/srv-biz 目录下，否则将造成程序更新异常
                  。</span
                >
              </template>
              <i-icons-question class="cursor-pointer question-icon" />
            </a-tooltip>
          </div>
        </template>
        <div class="w-full">
          <div class="text-xs text-5 mb-2 mt-[-8px]">请确保目录已存在</div>
          <a-input
            v-model="formData.cache_path"
            placeholder="请输入文件缓存路径"
            :max-length="2048"
            @input="
              (val) => (formData.cache_path = val.replace(/\s/g, ''))
            "></a-input>
        </div>
      </a-form-item>
      <a-form-item
        label="磁盘空间"
        field="cache_size"
        hide-asterisk
        asterisk-position="end"
        required>
        <section class="cloud-diverse-select">
          <a-input-number
            v-model="formData.cache_size"
            :max-length="13"
            class="!w-100">
            <template #append>
              <a-select v-model="diskFileSizeUnit" :options="diskOptions">
              </a-select>
            </template>
          </a-input-number>
        </section>
      </a-form-item>
    </a-form>
  </basic-drawer>
</template>

<script setup lang="ts">
import { getApiNodeApi, updateApiNodeApi } from '@/apis/modules/node/node'
import { getApiResolveRegionsListApi } from '@/apis/modules/resolve/area'
import type { FieldRule } from '@arco-design/web-vue'
import { cloneDeep, omit } from 'lodash-es'

interface IEmit {
  (event: 'update:visible', value: boolean): void
  (event: 'update:record', value: string): void
  (event: 'save'): void
}

interface IProps {
  visible: boolean
  record?: string
}

const emit = defineEmits<IEmit>()
const props = defineProps<IProps>()

const originData = ref()
// 节点数据
const { loading, request: getNodeInfo } = useRequest(getApiNodeApi, {
  success(res) {
    originData.value = cloneDeep(res)
    coverObjectValue(formData, res!)
    const { value, unit } = separateNumberAndLetter(res!.cache_size!)
    formData.cache_size = Number(value)
    const index = diskOptions.find((item) => item.label === unit)
      ?.value as number
    diskFileSizeUnit.value = index ?? 2
    formData.region_id = res!.region_info!.id!
    formData.cascade_ip = res!.cascade_ip! ? res!.cascade_ip! : ''
  }
})
const {
  formRef,
  formData,
  formRules: templateRules,
  diskFileSizeUnit
} = useNodeTemplateConfig({
  name: '',
  region_id: '',
  cascade_level: 1,
  enable_resolve: true,
  cascade_port: 8080,
  cascade_ip: ''
})
const formRules = computed<Record<string, FieldRule[]>>(() => {
  return {
    name: [
      { required: true, message: '请输入节点名称' },
      { min: 4, max: 32, message: '输入长度4-32个字符' }
    ],
    region_id: [{ required: true, message: '请选择节点区域' }],
    // cascade_ip: [
    //   {
    //     validator(value, callback) {
    //       if (!value) {
    //         return callback('请选择级联IP')
    //       }
    //       callback()
    //     }
    //   }
    // ],
    cascade_port: [
      { required: true, message: '请输入级联端口' },
      {
        validator(value, callback) {
          if (Number(value) < 1024 || Number(value) > 65535) {
            return callback('取值范围1024-65535')
          }
          if ([8000, 9000].includes(Number(value))) {
            return callback('端口不能为8000，9000')
          }
          callback()
        }
      }
    ],
    ...templateRules.value
  }
})

// 区域列表数据
const { data: regionList, run: getRegions } = useListRequest(
  getApiResolveRegionsListApi,
  {
    params: { offset: 0, limit: -1 }
  }
)

// 节点信息回显
watch(
  () => props.record,
  async () => {
    if (!props.record) {
      return
    }
    await getNodeInfo({ id: props.record })
    await getRegions()
  }
)

// 保存节点信息
const { loading: saveLoading, request: saveRequest } =
  useRequest(updateApiNodeApi)
async function handleSave() {
  const error = await formRef.value?.validate()
  if (error) return false
  const symbol = diskOptions.find(
    (item) => item.value === diskFileSizeUnit.value
  )?.label
  const data = cloneDeep({
    ...(omit(formData, ['ips', 'ip']) as any),
    id: props.record,
    //为空为主ip
    cascade_ip: formData.cascade_ip,
    cache_size: `${formData.cache_size}${symbol}`
  })
  async function fn() {
    await saveRequest(data).then(() => {
      emit('update:visible', false)
      emit('save')
      ToastUtils.success('操作成功')
    })
  }
  if (
    data.cache_path !== originData.value?.cache_path ||
    data.cache_size !== originData.value?.cache_size
  ) {
    CloudModal.error(
      {
        content: '修改缓存路径或磁盘空间需要重启节点，确认继续？'
      },
      fn
    )
  } else {
    fn()
  }
}
function handleClose() {
  emit('update:visible', false)
  formRef?.value?.resetFields()
}
</script>

<style scoped lang="less">
.reduce-gap {
  :deep(.arco-form-item-wrapper-col) {
    min-height: 24px;
  }
  :deep(.arco-form-item-content) {
    min-height: 24px;
  }
}
</style>
